using MemoryPack;
using System;
using System.Runtime.InteropServices;

namespace Voxels {
	[Serializable]
	[MemoryPackable]
	[StructLayout(LayoutKind.Sequential)]
	public partial struct BlockData {
		public BlockType Type;
		public byte Subtype;
		public byte SunLevel;
		public byte Flags;
		public ushort AddColor;
		public ushort Metadata;

		[MemoryPackIgnore]
		public BlockDescription Info {
			get {
				return StaticResources.BlocksInfo.GetBlockDescription(Type);
			}
		}

		public BlockData(BlockType type) {
			Type = type;
			Subtype = 0;
			Metadata = 0;
			SunLevel = 0;
			Flags = 0;
			AddColor = 65535;
		}

		public BlockData(BlockType type, byte subtype) {
			Type = type;
			Subtype = subtype;
			Metadata = 0;
			SunLevel = 0;
			Flags = 0;
			AddColor = 65535;
		}

		public BlockData(BlockType type, byte subtype, byte sunLevel, byte flags, ushort addColor, ushort metadata) {
			Type = type;
			Subtype = subtype;
			Metadata = metadata;
			SunLevel = sunLevel;
			AddColor = addColor;
			Flags = flags;
		}

		public static BlockData Empty {
			get {
				return new BlockData(BlockType.Air);
			}
		}

		public bool IsEmpty() {
			return Type == BlockType.Air;
		}

		public bool EqualsExcludeLightAndColor(BlockData other) {
			return Type == other.Type && Subtype == other.Subtype && Metadata == other.Metadata && Flags == other.Flags;
		}

		public override bool Equals(object obj) {
			return base.Equals(obj);
		}

		public override int GetHashCode() {
			return base.GetHashCode();
		}

		public static bool operator ==(BlockData a, BlockData b) {
			return a.Type == b.Type && a.Subtype == b.Subtype && a.Metadata == b.Metadata && a.AddColor == b.AddColor && a.SunLevel == b.SunLevel && a.Flags == b.Flags;
		}
		public static bool operator !=(BlockData a, BlockData b) {
			return a.Type != b.Type || a.Subtype != b.Subtype || a.Metadata != b.Metadata || a.AddColor != b.AddColor || a.SunLevel != b.SunLevel && a.Flags == b.Flags;
		}
	}
}
